#include "mqttProtocol.h"
#include <iostream>  
#include <sstream>
#include <cstring>

// 基础64编码字符集
static const char* base64Chars = 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// ===========================
// ControlMessage implementation
// ===========================

ControlMessage ControlMessage::fromJson(const std::string& jsonStr) {
    ControlMessage msg;
    try {
        auto j = nlohmann::json::parse(jsonStr);
        
        if (j.contains("defect_types")) {
            for (int type : j["defect_types"]) {
                msg.defectTypes.push_back(static_cast<DefectType>(type));
            }
        }
        
        if (j.contains("slot_mapping")) {
            msg.slotMapping = j["slot_mapping"].get<std::vector<int>>();
        }
        
        if (j.contains("control")) {
            std::string actionStr = j["control"];
            if (actionStr == "start") msg.action = ControlAction::START;
            else if (actionStr == "stop") msg.action = ControlAction::STOP;
            else if (actionStr == "pause") msg.action = ControlAction::PAUSE;
            else if (actionStr == "resume") msg.action = ControlAction::RESUME;
        }
        
        if (j.contains("product")) {
            auto& p = j["product"];
            if (p.contains("model")) msg.productInfo.model = p["model"];
            if (p.contains("batch")) msg.productInfo.batch = p["batch"];
            if (p.contains("serial")) msg.productInfo.serial = p["serial"];
        }
    } catch (const std::exception& e) {
        std::cerr << "Failed to decode control message: " << e.what() << std::endl;
    }
    return msg;
}

std::string ControlMessage::toJson() const {
    nlohmann::json j;
    
    std::vector<int> typeVec;
    for (DefectType type : defectTypes) {
        typeVec.push_back(static_cast<int>(type));
    }
    j["defect_types"] = typeVec;
    
    j["slot_mapping"] = slotMapping;
    
    std::string actionStr;
    switch (action) {
        case ControlAction::START: actionStr = "start"; break;
        case ControlAction::STOP: actionStr = "stop"; break;
        case ControlAction::PAUSE: actionStr = "pause"; break;
        case ControlAction::RESUME: actionStr = "resume"; break;
    }
    j["control"] = actionStr;
    
    nlohmann::json product;
    product["model"] = productInfo.model;
    product["batch"] = productInfo.batch;
    product["serial"] = productInfo.serial;
    j["product"] = product;
    
    return j.dump();
}

// ===========================
// ReportMessage implementation
// ===========================

bool ReportMessage::addDefect(DefectType type, float confidence, const std::string& location) {
    if (defectCount >= 8) return false;
    
    defects[defectCount].type = type;
    defects[defectCount].confidence = confidence;
    defects[defectCount].location = location;
    defectCount++;
    hasDefects = true;
    return true;
}

ReportMessage ReportMessage::fromJson(const std::string& jsonStr) {
    ReportMessage msg;
    try {
        auto j = nlohmann::json::parse(jsonStr);
        
        if (j.contains("timestamp")) {
            msg.timestamp = j["timestamp"];
        }
        
        if (j.contains("has_defects")) {
            msg.hasDefects = j["has_defects"];
        }
        
        if (j.contains("defects") && j["defects"].is_array()) {
            auto& arr = j["defects"];
            msg.defectCount = std::min((int)arr.size(), 8);
            for (int i = 0; i < msg.defectCount; i++) {
                auto& d = arr[i];
                msg.defects[i].type = static_cast<DefectType>(d["type"]);
                msg.defects[i].confidence = d["confidence"];
                msg.defects[i].location = d["location"];
            }
        }
        
        if (j.contains("location")) {
            auto& loc = j["location"];
            if (loc.contains("rack")) msg.storageLocation.rack = loc["rack"];
            if (loc.contains("slot")) msg.storageLocation.slot = loc["slot"];
        }
        
        if (j.contains("image")) {
            auto& img = j["image"];
            if (img.contains("thumbnail")) msg.image.thumbnail = img["thumbnail"];
            if (img.contains("width")) msg.image.width = img["width"];
            if (img.contains("height")) msg.image.height = img["height"];
            if (img.contains("format")) msg.image.format = img["format"];
            if (img.contains("data_size")) msg.image.dataSize = img["data_size"];
            
            // 从JSON中获取原始图像数据（如果存在）
            if (img.contains("raw_data") && img["raw_data"].is_string()) {
                std::string rawDataStr = img["raw_data"];
                msg.image.rawData.resize(rawDataStr.size());
                std::memcpy(msg.image.rawData.data(), rawDataStr.c_str(), rawDataStr.size());
            }
        }

        // 解析productInfo相关字段
        if (j.contains("product")) {
            auto& p = j["product"];
            if (p.contains("model")) msg.productInfo.model = p["model"];
            if (p.contains("batch")) msg.productInfo.batch = p["batch"];
            if (p.contains("serial")) msg.productInfo.serial = p["serial"];
        }

    } catch (const std::exception& e) {
        std::cerr << "Failed to decode report message: " << e.what() << std::endl;
    }
    return msg;
}

std::string ReportMessage::toJson() const {
    nlohmann::json j;
    j["timestamp"] = timestamp;
    j["has_defects"] = hasDefects;
    
    nlohmann::json defectArray = nlohmann::json::array();
    for (int i = 0; i < defectCount; i++) {
        nlohmann::json d;
        d["type"] = static_cast<int>(defects[i].type);
        d["confidence"] = defects[i].confidence;
        d["location"] = defects[i].location;
        defectArray.push_back(d);
    }
    j["defects"] = defectArray;
    
    nlohmann::json location;
    location["rack"] = storageLocation.rack;
    location["slot"] = storageLocation.slot;
    j["location"] = location;
    
    nlohmann::json img;
    img["thumbnail"] = image.thumbnail;
    img["width"] = image.width;
    img["height"] = image.height;
    img["format"] = image.format;
    img["data_size"] = image.dataSize;
    j["image"] = img;
    // 将原始图像数据转换为字符串存储（若需要可启用）
    // if (!image.rawData.empty()) {
    //     img["raw_data"] = std::string(reinterpret_cast<const char*>(image.rawData.data()), 
    //                                  image.rawData.size());
    // }

    // 序列化productInfo相关字段
    nlohmann::json product;
    product["model"] = productInfo.model;
    product["batch"] = productInfo.batch;
    product["serial"] = productInfo.serial;
    j["product"] = product;
    
    return j.dump();
}

// ===========================
// ProtocolHandler implementation
// ===========================

ProtocolHandler& ProtocolHandler::getInstance() {
    static ProtocolHandler instance;
    return instance;
}

// V4L2图像数据转Base64（假设原始数据为JPEG格式）
std::string ProtocolHandler::imageToBase64(const std::vector<uint8_t>& rawData, int width, int height, 
                                         const std::string& format, int quality) {
    // 直接对原始图像数据进行Base64编码
    std::string base64;
    base64.reserve(rawData.size() * 4 / 3 + 1);
    
    for (size_t i = 0; i < rawData.size(); i += 3) {
        uint32_t b = (rawData[i] << 16);
        if (i + 1 < rawData.size()) b |= (rawData[i + 1] << 8);
        if (i + 2 < rawData.size()) b |= rawData[i + 2];
        
        base64 += base64Chars[(b >> 18) & 0x3F];
        base64 += base64Chars[(b >> 12) & 0x3F];
        if (i + 1 < rawData.size()) base64 += base64Chars[(b >> 6) & 0x3F];
        if (i + 2 < rawData.size()) base64 += base64Chars[b & 0x3F];
    }
    
    // 处理可能的填充
    int padding = (3 - rawData.size() % 3) % 3;
    for (int i = 0; i < padding; i++) {
        base64 += '=';
    }
    
    return base64;
}

// Base64转V4L2图像数据
std::vector<uint8_t> ProtocolHandler::base64ToImage(const std::string& base64Str, int& width, int& height, 
                                                 std::string& format) {
    std::vector<uint8_t> rawData;
    rawData.reserve(base64Str.size() * 3 / 4);
    
    for (size_t i = 0, j = 0; i < base64Str.size(); i++) {
        char c = base64Str[i];
        if (c == '=') break;  // 处理填充
        
        int val = -1;
        for (int k = 0; k < 64; k++) {
            if (base64Chars[k] == c) {
                val = k;
                break;
            }
        }
        
        if (val == -1) continue;
        
        switch (j % 4) {
            case 0: rawData.push_back(val << 2); break;
            case 1: rawData[j / 4 - 1] |= val >> 4; rawData.push_back((val & 0x0F) << 4); break;
            case 2: rawData[j / 4 - 1] |= val >> 2; rawData.push_back((val & 0x03) << 6); break;
            case 3: rawData[j / 4 - 1] |= val; break;
        }
        j++;
    }
    
    // 假设图像尺寸和格式通过其他方式获取，这里仅作为示例
    width = 640;    // 默认宽度
    height = 480;   // 默认高度
    format = "jpeg"; // 默认格式
    
    return rawData;
}

std::string ProtocolHandler::encodeControlMessage(const ControlMessage& msg) {
    return msg.toJson();
}

ControlMessage ProtocolHandler::decodeControlMessage(const std::string& jsonStr) const{
    return ControlMessage::fromJson(jsonStr);
}

std::string ProtocolHandler::encodeReportMessage(const ReportMessage& msg) {
    return msg.toJson();
}

ReportMessage ProtocolHandler::decodeReportMessage(const std::string& jsonStr) {
    return ReportMessage::fromJson(jsonStr);
}